﻿using BasicInformation.ApiRead.Application.Command.Location;
using BasicInformation.Domain;
using BasicInformation.Dtos;
using BasicInformation.ErrorCode;
using BasicInformation.Infrastructure.Implement;
using BasicInformation.Infrastructure.Interface;
using Dapper;
using MediatR;
using System.Text;

namespace BasicInformation.ApiRead.Application.Handler.Location
{
    /// <summary>
    /// 获取库位信息的分页查询处理器
    /// </summary>
    public class GetLocationHandler : IRequestHandler<GetLocationCommand, ApiPaging<LocationDTO>>
    {
        private readonly ILogger<GetLocationHandler> logger;
        private readonly DatabaseContext db;

        /// <summary>
        /// 构造函数，注入日志和数据库上下文
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="db">数据库上下文</param>
        public GetLocationHandler(ILogger<GetLocationHandler> logger, DatabaseContext db)
        {
            this.logger = logger;
            this.db = db;
        }

        /// <summary>
        /// 处理获取库位信息的请求
        /// </summary>
        /// <param name="request">查询请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>分页查询结果</returns>
        public async Task<ApiPaging<LocationDTO>> Handle(GetLocationCommand request, CancellationToken cancellationToken)
        {
            // 初始化返回结果对象
            ApiPaging<LocationDTO> result = new ApiPaging<LocationDTO>();

            // 创建SQL查询字符串构建器
            StringBuilder sql = new StringBuilder();
            StringBuilder countSql = new StringBuilder();

            // 构建主查询SQL - 获取库位详细信息（关联库位类型和仓库表）
            sql.Append(@"SELECT 
                        a.LocationId,
                        a.LocationCode,
                        a.LocationName,
                        a.LocationRemark,
                        b.LTypeId,
                        b.LTypeName,
                        c.DepotId,
                        c.DepotName,
                        a.CreatTime
                        FROM locationmodel AS a
                        JOIN locationtypemodel AS b
                            ON a.LTypeId =b.LTypeId
                        JOIN depotmodel AS c
                            ON a.DepotId = c.DepotId
                        WHERE a.IsDel=0 ");

            // 构建计数SQL - 只查询总记录数
            countSql.Append(@"SELECT COUNT(*)
                            FROM locationmodel
                            WHERE IsDel=0");

            // 添加查询条件 - 库位编号模糊查询
            if (!string.IsNullOrEmpty(request.LocationCode))
            {
                sql.Append(" AND a.LocationCode = @LocationCode");  // 注意前面加空格
                countSql.Append(" AND LocationCode = @LocationCode");  // 注意前面加空格
            }

            // 添加查询条件 - 库位名称模糊查询
            if (!string.IsNullOrEmpty(request.LocationName))
            {
                sql.Append(" AND a.LocationName LIKE @LName");  // 精确查询使用=而不是LIKE
                countSql.Append(" AND LocationName LIKE @LName");
            }

            // 添加查询条件 - 仓库ID精确查询
            if (request.DepotId > 0)
            {
                sql.Append(" AND a.DepotId = @DepotId");  // 注意前面加空格并指定表别名
                countSql.Append(" AND DepotId = @DepotId");  // 注意前面加空格
            }

            // 添加排序和分页
            sql.Append(" ORDER BY a.CreatTime DESC LIMIT @size OFFSET @offset");

            // 正确设置模糊查询参数
            var parameters = new
            {
                LocationCode = request.LocationCode,  // 精确查询不需要加%
                LName = string.IsNullOrEmpty(request.LocationName) ? null : $"%{request.LocationName}%",
                DepotId = request.DepotId,
                offset = (request.index - 1) * request.size,
                size = request.size
            };

            try
            {
                // 执行查询
                var pageData = await db.DapperConnection.QueryAsync<LocationDTO>(sql.ToString(), parameters);
                //执行总页查询
                int totalCount = await db.DapperConnection.ExecuteScalarAsync<int>(countSql.ToString(), parameters);
                //计算总页数
                int totalPage = (int)Math.Ceiling(totalCount / (double)request.size);

                // 设置返回结果
                result.Msg = "库位管理查询成功";
                result.Code = ApiEnum.OK;
                result.Data = pageData.ToList();
                result.TotalCount = totalCount;
                result.TotalPCount = totalPage;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "查询库位信息时发生错误");
                result.Msg = "查询库位信息时发生错误";
                result.Code = ApiEnum.Fail;
            }
            return await Task.FromResult(result);
        }
    }
}